package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"time"
)

const (
	diBasePath = "/sys/class/dido/di"  // DI设备基础路径
	diCount    = 18                    // DI数量
	doBasePath = "/sys/class/dido/do"   // DO设备基础路径
	doCount    = 10                    // DO数量
)

// 读取单个DI状态
func readDIState(diNum int) (int, error) {
	path := filepath.Join(basePath, fmt.Sprintf("di%d", diNum), "value")
	
	data, err := os.ReadFile(path)
	if err != nil {
		return 0, fmt.Errorf("读取DI%d失败: %v", diNum, err)
	}

	state, err := strconv.Atoi(string(data[0]))
	if err != nil {
		return 0, fmt.Errorf("解析DI%d状态失败: %v", diNum, err)
	}

	return state, nil
}

// 读取所有DI状态
func readAllDI() (map[int]int, error) {
	states := make(map[int]int, diCount)

	for i := 1; i <= diCount; i++ {
		state, err := readDIState(i)
		if err != nil {
			return nil, err
		}
		states[i] = state
	}

	return states, nil
}

// 写入单个DO状态
func writeDOState(doNum int, state int) error {
	path := filepath.Join(doBasePath, fmt.Sprintf("do%d", doNum), "value")
	
	file, err := os.OpenFile(path, os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("打开DO%d失败: %v", doNum, err)
	}
	defer file.Close()

	_, err = file.WriteString(strconv.Itoa(state))
	if err != nil {
		return fmt.Errorf("写入DO%d失败: %v", doNum, err)
	}

	return nil
}

// 读取所有DO状态
func readAllDO() (map[int]int, error) {
	states := make(map[int]int, doCount)

	for i := 1; i <= doCount; i++ {
		path := filepath.Join(doBasePath, fmt.Sprintf("do%d", i), "value")
		data, err := os.ReadFile(path)
		if err != nil {
			return nil, fmt.Errorf("读取DO%d失败: %v", i, err)
		}

		state, err := strconv.Atoi(string(data[0]))
		if err != nil {
			return nil, fmt.Errorf("解析DO%d状态失败: %v", i, err)
		}
		states[i] = state
	}

	return states, nil
}

func main() {
	// 示例：设置DO1为高电平
	err := writeDOState(1, 1)
	if err != nil {
		fmt.Printf("设置DO失败: %v\n", err)
	}

	// 持续监测DI和DO状态
	for {
		states, err := readAllDI()
		if err != nil {
			fmt.Printf("读取错误: %v\n", err)
			time.Sleep(1 * time.Second)
			continue
		}

		fmt.Println("当前DI状态:")
		for di, state := range states {
			fmt.Printf("DI%d: %d\t", di, state)
			if di%6 == 0 { // 每6个DI换行显示
				fmt.Println()
			}
		}
		fmt.Println("\n------------------")

		// 新增DO状态读取
		doStates, err := readAllDO()
		if err != nil {
			fmt.Printf("读取DO错误: %v\n", err)
		} else {
			fmt.Println("当前DO状态:")
			for do, state := range doStates {
				fmt.Printf("DO%d: %d\t", do, state)
				if do%5 == 0 {
					fmt.Println()
				}
			}
			fmt.Println("\n==================")
		}

		time.Sleep(500 * time.Millisecond)
	}
}